﻿using System;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Globalization;

namespace LanguageInfo.Common.Utilities
{
	/// <summary>
	/// 描述：数字帮助类
	/// 作者：路晓阳
	/// 时间：2010-6-1
	/// </summary>
	public static class NumberHelper
	{

		/// <summary>
		/// Determines whether [is natural number] [the specified s item].
		/// </summary>
		/// <param name="sItem">The s item.</param>
		/// <returns>
		/// 	<c>true</c> if [is natural number] [the specified s item]; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsNaturalNumber(string sItem)
		{
			Regex notNaturalPattern = new Regex("[^0-9]");
			Regex naturalPattern = new Regex("0*[1-9][0-9]*");

			return !notNaturalPattern.IsMatch(sItem) && naturalPattern.IsMatch(sItem);
		}

		/// <summary>
		/// Determines whether [is whole number] [the specified s item].
		/// </summary>
		/// <param name="sItem">The s item.</param>
		/// <returns>
		/// 	<c>true</c> if [is whole number] [the specified s item]; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsWholeNumber(string sItem)
		{
			Regex notWholePattern = new Regex("[^0-9]");
			return !notWholePattern.IsMatch(sItem);
		}

		/// <summary>
		/// Determines whether the specified s item is integer.
		/// </summary>
		/// <param name="sItem">The s item.</param>
		/// <returns>
		/// 	<c>true</c> if the specified s item is integer; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsInteger(string sItem)
		{
			Regex notIntPattern = new Regex("[^0-9-]");
			Regex intPattern = new Regex("^-[0-9]+$|^[0-9]+$");

			return !notIntPattern.IsMatch(sItem) && intPattern.IsMatch(sItem);
		}

		/// <summary>
		/// Determines whether the specified s item is number.
		/// </summary>
		/// <param name="sItem">The s item.</param>
		/// <returns>
		/// 	<c>true</c> if the specified s item is number; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsNumber(string sItem)
		{
			double result;
			return (double.TryParse(sItem, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.CurrentInfo, out result));
		}

		/// <summary>
		/// Determines whether the specified value is an even number.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <returns>
		/// 	<c>true</c> if the specified value is even; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsEven(int value)
		{
			return ((value & 1) == 0);
		}

		/// <summary>
		/// Determines whether the specified value is an odd number.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <returns>
		/// 	<c>true</c> if the specified value is odd; otherwise, <c>false</c>.
		/// </returns>
		public static bool IsOdd(int value)
		{
			return ((value & 1) == 1);
		}

		/// <summary>
		/// Generates a random number
		/// </summary>
		/// <param name="noZeros"></param>
		/// <returns></returns>
		public static int Random(bool noZeros)
		{
			byte[] random = new Byte[1];
			RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
			if (noZeros)
			{
				rng.GetNonZeroBytes(random);
			}
			else
			{
				rng.GetBytes(random);
			}
			return random[0];
		}

		/// <summary>
		/// Generates a random number with an upper bound
		/// </summary>
		/// <param name="high"></param>
		/// <returns></returns>
		public static int Random(int high)
		{
			byte[] random = new Byte[4];
			new RNGCryptoServiceProvider().GetBytes(random);
			int randomNumber = BitConverter.ToInt32(random, 0);

			return Math.Abs(randomNumber % high);
		}

		/// <summary>
		/// Generates a random number between the specified bounds
		/// </summary>
		/// <param name="low"></param>
		/// <param name="high"></param>
		/// <returns></returns>
		public static int Random(int low, int high)
		{
			return new Random().Next(low, high);
		}

		/// <summary>
		/// Generates a random double
		/// </summary>
		/// <returns></returns>
		public static double Random()
		{
			return new Random().NextDouble();
		}

		/// <summary>
		/// 转换为int，如不能转换返回0
		/// </summary>
		/// <param name="src"></param>
		/// <returns></returns>
		public static int GetVal(object src)
		{
			int val = 0;
			if (null != src)
				int.TryParse(src.ToString(), 
					NumberStyles.AllowThousands | NumberStyles.AllowLeadingWhite 
					| NumberStyles.AllowTrailingWhite | NumberStyles.AllowTrailingSign
					| NumberStyles.AllowLeadingSign, CultureInfo.CurrentUICulture, out val);
			return val;
		}
		/// <summary>
		/// 转换为int，如不能转换返回给定的值
		/// </summary>
		/// <param name="src"></param>
		/// <returns></returns>
		public static int GetVal(object src, int _default)
		{
			int val = 0;
			if (null != src)
				if (!int.TryParse(src.ToString(), out val))
					val = _default;
			return val;
		}

		/// <summary>
		/// 转换为byte，如不能转换返回0
		/// </summary>
		/// <param name="src"></param>
		/// <returns></returns>
		public static byte GetByte(object src)
		{
			byte val = 0;
			if (null != src)
				byte.TryParse(src.ToString(), out val);
			return val;
		}
		/// <summary>
		/// 转换为byte，如不能转换返给定的值
		/// </summary>
		/// <param name="src"></param>
		/// <returns></returns>
		public static byte GetByte(object src, byte _default)
		{
			byte val = _default;
			if (null != src)
				if (!byte.TryParse(src.ToString(), out val))
					val = _default;
			return val;
		}

		/// <summary>
		/// 转换为decimal，如不能转换返回0
		/// </summary>
		/// <param name="src"></param>
		/// <returns></returns>
		public static decimal GetDecimal(object src)
		{
			decimal val = 0;
			if (null != src)
				decimal.TryParse(src.ToString(), out val);
			return val;
		}

		public static double GetDouble(object src)
		{
			double val = 0;
			if (null != src)
				double.TryParse(src.ToString(), out val);
			return val;
		}

	}
}
